# 417. 太平洋大西洋水流问题
// 有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。
const { flow } = require("lodash");
// 这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。
// 岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。
// 返回网格坐标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋 。
/**
* @param {number[][]} heights
* @return {number[][]}
*/
var pacificAtlantic = function(heights) {
if (!heights || !heights[0]) return [];
const m = heights.length; // 行
const n = heights[0].length; // 列
// 生成图
const flow1 = Array.from({ length: m }, () => new Array(n).fill(false));
const flow2 = Array.from({ length: m }, () => new Array(n).fill(false));
function dfs(r, c, flow) {
flow[r][c] = true;
[
[r - 1, c],
[r + 1, c],
[r, c - 1],
[r, c + 1],
].forEach(([nr, nc]) => {
if (
nr >= 0 &&
nc >= 0 &&
nr < m &&
nc < n &&
// 防止死循环
!flow[nr][nc] &&
// 保证逆流而上
heights[nr][nc] >= heights[r][c]
) {
dfs(nr, nc, flow);
}
});
}
// 沿着海岸线逆流而上
// 自上而下
for (let i = 0; i < m; i++) {
dfs(i, 0, flow1);
dfs(i, n - 1, flow2);
}
for (let i = 0; i < n; i++) {
dfs(0, i, flow1);
dfs(m - 1, i, flow2);
}
const res = [];
// 两层循环判断都可以流入的位置, 表示中间线
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (flow1[i][j] && flow2[i][j]) {
res.push([i, j]);
}
}
}
return res;
};
console.log(
pacificAtlantic([
[1, 2, 2, 3, 5],
[3, 2, 3, 4, 4],
[2, 4, 5, 3, 1],
[6, 7, 1, 4, 5],
[5, 1, 1, 2, 4],
])
); // [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77